<script setup>
import { ref, onMounted, computed, provide } from 'vue'
import ObjectEditor from './components/ObjectEditor.vue'

const valueWithVersions = ref({})
const versions = ref([])
onMounted(async () => {
    const response = await fetch('http://localhost:8080/db/db/config')
    const json = await response.json()
    valueWithVersions.value = json.data.valueWithVersions
    versions.value = json.data.versions
})
const menus = ref([])
const isMerge = ref(false)
const changeValue = ref({})
const changes = ref([])
const hasError = ref(false)
const json = ref('')
const updateValue = (path, prop, value) => {
    let temp = changeValue.value
    path.forEach(it => {
        if (!temp[it]) {
            temp[it] = {}
        }
        temp = temp[it]
    })
    temp[prop] = value
    json.value = JSON.stringify(changeValue.value, null, 4)
    console.log(json.value)
}
provide('ids', menus)
provide('isMerge', isMerge)
provide('changeValue', changeValue)
provide('updateChangeValue', (path, prop, value) => {
    if (hasError.value) {
        changes.value.push({
            path,
            prop,
            value
        })
    } else {
        updateValue(path, prop, value)
    }
})

const onChange = () => {
    try {
        changeValue.value = JSON.parse(json.value)
        if (changes.value.length > 0) {
            onForceUpdate()
        }
        hasError.value = false
    } catch (error) {
        hasError.value = true
    }
}
const onForceUpdate = () => {
    while (changes.value.length > 0) {
        let { path, prop, value } = changes.value.pop()
        updateValue(path, prop, value)
    }
}
const onFormat = () => {
    const data = JSON.parse(json.value)
    json.value = JSON.stringify(data, null, 4)
}
const onSave = async () => {
    const response = await fetch('http://localhost:8080/db/db/update', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            data: changeValue.value,
            name: 123
        })
    })
    const json1 = await response.json()
    console.log('保存结果', json1)
}
</script>

<template>
    <div>
        <div style="display: flex">
            <n-card class="flex-1" title="配置对象">
                <ObjectEditor class="flex-1" :value="valueWithVersions" />
            </n-card>
            <div class="flex-1">
                <n-card title="配置来源">
                    <n-checkbox-group v-model:value="menus">
                        <n-flex :size="0">
                            <n-checkbox v-for="item in versions" :value="item" :label="item" />
                        </n-flex>
                    </n-checkbox-group>
                </n-card>
                <n-card title="控制按钮">
                    <n-checkbox v-model:checked="isMerge">叠加</n-checkbox>
                    <n-checkbox v-model:checked="isMerge">可编辑</n-checkbox>
                    <n-checkbox v-model:checked="isMerge">双击编辑</n-checkbox>
                </n-card>
                <div>
                    <n-input v-model:value="json" placeholder="基本的 Textarea" />
                    <n-button v-if="hasError">格式错误，请检查</n-button>
                    <n-button v-if="changes.length != 0" @click="onForceUpdate">
                        丢弃错误，强制更新
                    </n-button>
                </div>
                <div class="preview flex-1">
                    <n-input
                        class="in"
                        @input="onChange"
                        v-model:value="json"
                        type="textarea"
                        placeholder="基本的 Textarea" />
                    <div class="flex-end">
                        <n-button @click="onFormat">格式化</n-button>
                        <n-button @click="onSave">保存</n-button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<style scoped>
.flex-1 {
    flex: 1;
}
.in {
    width: 100%;
    height: 100%;
}
.preview {
    position: relative;
}
.tips {
    position: absolute;
    left: 0;
    top: 0;
    transform: translateY(-100%);
}

.flex {
    display: flex;
}

.flex-end {
    display: flex;
    justify-content: flex-end;
}
</style>
